package restaurant;

/**
 * Orders Class stores and manipulates order item objects.
 * 
 * @author SG350, CT267, MSM41.
 */
import java.util.ArrayList;
import java.util.Map;
import java.util.TreeMap;
import java.util.TreeSet;

public class Orders {

	/**
	 * Field variables.
	 */
	private double grandTotalAllTables;
	private IOsystem io = null;
	private ArrayList<OrderItem> orderList = null;
	private TreeSet<MenuItem> menuTreeSet = null;
	private TreeMap<String, Integer> itemDetailTreeMap = null;
	private TreeMap<Integer, TreeMap<String, Integer>> orderTreeMap = null;

	/**
	 * Constructor creates new IOsystem object and populates an ArrayList.
	 * 
	 * @param menuItemSet
	 */
	public Orders(TreeSet<MenuItem> menuItemSet) {
		if(menuItemSet==null){
			throw new IllegalArgumentException("Data structure is Empty");
		}else{
			io = new IOsystem();
			orderList = new ArrayList<OrderItem>(
					io.readOrderFile("order_input.txt"));
			menuTreeSet = new TreeSet<MenuItem>(menuItemSet);
			treeMapForTableSummary();
		}
		
	}

	/**
	 * ArrayList is used to hold details from input file for ordered items and
	 * display then in workable list.
	 * 
	 * @return orderList
	 */
	public ArrayList<OrderItem> getOrderList() {
		return orderList;
	}

	/**
	 * Creates Tables Summary for Report using data stored in treeMapOrders
	 * TreeMap.
	 * 
	 * @return output
	 */
	public String getTableSummary() {

		double total = 0.0;
		double grandTotal = 0.0;

		TreeMap<String, Integer> currentMenuItems;

		String output = ("=============TABLE SUMMARY=============\n");
		for (Map.Entry<Integer, TreeMap<String, Integer>> tableIDentry : orderTreeMap
				.entrySet()) {
			output += ("================================\nTABLE "
					+ tableIDentry.getKey() + "\n");

			currentMenuItems = orderTreeMap.get(tableIDentry.getKey());

			for (Map.Entry<String, Integer> menuItemEntry : currentMenuItems
					.entrySet()) {
				double price = 0.0;
				double pricePerItem = 0.0;
				String menuItem = menuItemEntry.getKey();
				int quantity = menuItemEntry.getValue();

				for (MenuItem mi : menuTreeSet) {
					if (mi.getDish().contains(menuItem)) {
						price = mi.getCost();
						pricePerItem = price * quantity;
					}
				}
				output += (String.format("%-12s", menuItem.toUpperCase()) + " "
						+ quantity + " * " + "£" + String.format("%.2f", price)
						+ " = " + "£" + String.format("%.2f", pricePerItem) + "\n");
				total += pricePerItem;
			}

			String discountArr[] = getDiscount(total);
			double discount = Double.parseDouble(discountArr[1]);

			output += ("\nSUBTOTAL: £" + String.format("%.2f", total) + "\n");
			output += ("DISCOUNT: " + discountArr[0] + "-£"
					+ String.format("%.2f", discount) + "\n");

			total -= discount;
			output += ("TABLE TOTAL: £" + String.format("%.2f", total) + "\n");
			output += ("================================\n\n");

			grandTotal += total;
			total = 0;
		}
		output += ("GRAND TOTAL, ALL TABLES: £" + String.format("%.2f",
				grandTotal));
		output += ("\n=======================================\n");

		return output;
	}

	/**
	 * Two TreeMaps are created. First TreeMap with Key: Table ID, Value:
	 * Another TreeMap with Key: Dish, Value Quantity. TreeMaps store data in an
	 * order and avoids Key duplication.
	 */
	public void treeMapForTableSummary() {
		orderTreeMap = new TreeMap<Integer, TreeMap<String, Integer>>();
		/*
		 * Read data for Table Id, Menu Item name and Quantity from ArrayList of
		 * OrderItems and enter in TreeMaps.
		 */
		for (OrderItem o : orderList) {
			int tableID = o.getTableid();
			String menuItem = o.getName();
			int quantity = o.getQuantity();

			/* Add to TreeMap only if the Key for Table ID does not exist. */
			if (!orderTreeMap.containsKey(tableID)) {
				itemDetailTreeMap = new TreeMap<String, Integer>();
				itemDetailTreeMap.put(menuItem, quantity);
				orderTreeMap.put(tableID, itemDetailTreeMap);
			} else {
				/*
				 * A Key with Table ID has been found in TreeMap Search the
				 * corresponding teeeMap for Value and see if the Dish exists in
				 * Key or not If Dish is found as key, increment the quantity If
				 * Dish is not found as key, enter new key-value pair in second
				 * TreeMap (i.e., the value of the first TreeMap).
				 */
				TreeMap<String, Integer> currentDishes = orderTreeMap
						.get(tableID);

				if (currentDishes.containsKey(menuItem)) {
					int updatedQuantity = currentDishes.get(menuItem)
							+ quantity;
					currentDishes.put(menuItem, updatedQuantity);
					orderTreeMap.put(tableID, currentDishes);
				} else {
					currentDishes.put(menuItem, quantity);
					orderTreeMap.put(tableID, currentDishes);
				}
			}
		}
	}

	/**
	 * Return all items in the orderList ArrayList.
	 * 
	 * @return output
	 */
	public String getOrderItems() {
		String output = "";
		for (OrderItem li : orderList) {
			output += String.format("%-12s", li.getTableid())
					+ String.format("%-15s", li.getName()) + li.getQuantity()
					+ "\n";
		}
		return output;
	}
	 public String getIndividualTableSummary(int tableID) {
			String output = " ";
			String meuItem = "";
			int quantity = 0;
			double price = 0.0;
			double pricePerItem = 0.0;
			double total = 0.0;
			
			

			TreeMap<String, Integer> currentMenuItems;

			output += ("================================");
			output += ("\nTABLE " + tableID + "\n");

			currentMenuItems = orderTreeMap.get(tableID);

			for (Map.Entry<String, Integer> menuItemEntry : currentMenuItems
					.entrySet()) {
				meuItem = menuItemEntry.getKey();
				quantity = menuItemEntry.getValue();

				for (MenuItem mi : menuTreeSet) {
					if (mi.getDish().contains(meuItem)) {
						price = mi.getCost();
						pricePerItem = price * quantity;
					}
				}

				output += (String.format("%-12s", meuItem.toUpperCase()) + " "
						+ quantity + " * " + "�" + String.format("%.2f", price)
						+ " = " + "�" + String.format("%.2f", pricePerItem) + "\n");
				total += pricePerItem;
			}
			
			grandTotalAllTables +=total;

			output += ("\nTOTAL FOR TABLE: �" + String.format("%.2f", total) + "\n");
			output += ("================================\n\n");

			return output;
		}

		public String getAllTablesSummary() {		
			String output = " ";
			
			grandTotalAllTables = 0;
			
			for (Map.Entry<Integer, TreeMap<String, Integer>> tableIDentry : orderTreeMap
					.entrySet()) {
				output += (this.getIndividualTableSummary(tableIDentry.getKey()));
			}		
			output += ("GRAND TOTAL, ALL TABLES: �" + String.format("%.2f",
					grandTotalAllTables));
			output += ("\n=======================================\n");
			
			return output;
		}	
	/**
	 * Return discount on total price. Discount calculation shown below.
	 * £10>..<£20 = 10%. £20>..<£30 = 20%. £30> = 25%
	 * 
	 * Returns string array with discount type and value.
	 * 
	 * @return discount
	 * 
	 */
	public String[] getDiscount(double value) {

		String[] discount = { "N/A", "0" };

		if (value >= 10.0 && value < 20.0) {
			discount[0] = "10% Applied!";
			discount[1] = (value * 0.10) + "";
			return discount;

		} else if (value >= 20.0 && value < 30.0) {
			discount[0] = "20% Applied!";
			discount[1] = (value * 0.20) + "";
			return discount;
		} else if (value >= 30.0) {
			discount[0] = "25% Applied!";
			discount[1] = (value * 0.25) + "";
			return discount;
		}

		return discount;
	}
}
